// 公共工具

#pragma once

#include <iostream>
#include <atomic>
#include <fstream>
#include <string>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <boost/algorithm/string.hpp>

namespace ns_util
{
	// 获取时间戳
	class TimeUtil
	{
	public:
		// 单位秒
		static std::string GetTimeStamp()
		{
			struct timeval tv;
			gettimeofday(&tv, nullptr);
			return std::to_string(tv.tv_sec);
		}
		// 单位毫秒
		static std::string GetTimeMs()
		{
			// struct timeval {
			// 	time_t      tv_sec;     /* seconds */
			// 	suseconds_t tv_usec;    /* microseconds */
			// };
			struct timeval tv;
			gettimeofday(&tv, nullptr);
			return std::to_string(tv.tv_sec * 1000 + tv.tv_usec / 1000);
		}
	};

	// 修改后缀
	const std::string temp_path = "./temp/";
	class PathUtil
	{
	public:
		// 修改后缀方法
		static std::string AddSuffix(const std::string &file_name, const std::string &suffix)
		{
			std::string path_name = temp_path;
			path_name += file_name;
			path_name += suffix;
			return path_name;
		}

		// 后缀不同类型的方法
		static std::string Src(const std::string &file_name)
		{
			return AddSuffix(file_name, ".cc");
		}
		static std::string Exe(const std::string &file_name)
		{
			return AddSuffix(file_name, ".exe");
		}
		static std::string CompileError(const std::string &file_name)
		{
			return AddSuffix(file_name, ".compile_error");
		}
		static std::string Stdin(const std::string &file_name)
		{
			return AddSuffix(file_name, ".stdin");
		}
		static std::string Stdout(const std::string &file_name)
		{
			return AddSuffix(file_name, ".stdout");
		}
		static std::string Stderr(const std::string &file_name)
		{
			return AddSuffix(file_name, ".stderr");
		}
	};

	// 文件操作
	class FileUtil
	{
	public:
		// 判断文件是否存在
		static bool IsFileExists(const std::string &file_name)
		{
			struct stat st;
			if (stat(file_name.c_str(), &st) == 0)
			{
				return true;
			}
			return false;
		}

		// 创建唯一文件名
		static std::string UniquFileName()
		{
			//采用原子操作，创建时重复
			std::atomic_uint id(0);
			id++;
			// 毫秒级时间戳+原子性递增唯一值: 来保证唯一性
			std::string ms = TimeUtil::GetTimeMs();
			std::string unique_id = ms + "_" + std::to_string(id);
			return unique_id;
		}	

		// 文件写操作
		static bool WriteFile(const std::string &src_name,const std::string &connent)
		{
			std::ofstream out(src_name);
			if(!out.is_open())
			{
				return false;
			}
			out.write(connent.c_str(),connent.size());
			out.close();
			return true;
		}

		// 文件读操作
		//keep保不保存换行符
		static bool ReadFile(const std::string &file_name, std::string *out, bool keep  = false)
		{
			std::ifstream in(file_name);
			if(!in.is_open())
			{
				return false;
			}
			std::string line;
			while(std::getline(in,line))
			{
				*out += line;
				if(keep)
				{
					*out += "\n";
				}
			}
			in.close();
			return true;
		}
	};

	// 字符串切割，用到boost库
	class StringUtil
	{
		public:
		/*************************************
         * str: 输入型，目标要切分的字符串
         * target: 输出型，保存切分完毕的结果
         * sep: 指定的分割符
         * **********************************/
		static void SplitStr(const std::string& str,std::vector<std::string> *target,std::string sep)
		{
			boost::split((*target),str,boost::is_any_of(sep),boost::algorithm::token_compress_on);
		}
	};
}